package biz.almas.uycnr.crawler.dao;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import biz.almas.uycnr.crawler.dao.factory.MemoryFactory;
import biz.almas.uycnr.crawler.entity.CnrDocument;
import biz.almas.uycnr.crawler.utils.KzWordConvertUtil;
import biz.almas.uycnr.crawler.utils.UyUtil;
import cn.ffcs.memory.BeanListHandler;
import cn.ffcs.memory.ColumnHandler;
import cn.ffcs.memory.Memory;

/**
 * @Description: 文档
 * @Copyright: Copyright (c) 2015 XinJiang Almas Software All Rights Reserved
 * @Company: XinJiang Almas Software
 * @author Ansar786 Nov 19, 2015
 * @version V1.0
 * @history:
 * 
 */
public class CnrDocumentDao {
	// 定义日志输出对象
	public static Logger logger = Logger.getLogger(CnrDocumentDao.class);
	// 获取Memory对象
	private Memory memory = MemoryFactory.getInstance();

	/**
	 * 存储文档列表 Ansar786 Nov 23, 2015
	 * 
	 * @param documents
	 * @param channelId
	 */
	public void storeDocuments(List<CnrDocument> documents, int channelId,
			int langId) {
		if (documents != null && documents.size() > 0) {
			List<CnrDocument> oldDocuments = getDocListByChannel(channelId,
					langId);
			if (oldDocuments.size() == 0) {
				saveDocuments(documents);
			} else {
				storeDocuments(oldDocuments, documents);
			}
			setStatus(channelId, documents);
		}
	}

	/**
	 * 获取文档列表 Ansar786 Nov 23, 2015
	 * 
	 * @param channelId
	 * @return
	 */
	public List<CnrDocument> getDocListByChannel(int channelId, int langId) {
		try {
			return memory
					.query("select * from cnr_document where doc_channel = ? and lang_id = ? and status = 1",
							new BeanListHandler<CnrDocument>(CnrDocument.class),
							channelId, langId);
		} catch (Exception e) {
			logger.error(e.toString());
			return null;
		}
	}

	/**
	 * 分出修改文档列表和新增文档列表 Ansar786 Nov 21, 2015
	 * 
	 * @param oldDocuments
	 * @param documents
	 */
	private void storeDocuments(List<CnrDocument> oldDocuments,
			List<CnrDocument> documents) {
		List<CnrDocument> updateList = new ArrayList<CnrDocument>();
		List<CnrDocument> addList = new ArrayList<CnrDocument>();
		for (CnrDocument document : documents) {
			// 定义变量用于标志新文档是否在旧文档列表中存在，如不存在，则该文档是新增的文档
			boolean isHave = false;
			// 用循环方式比较新的文档和旧的文档列表中每个文档
			for (int i = 0; i < oldDocuments.size(); i++) {
				// 如果旧的文档中存在，则比较修改时间
				if (document.getDocId() == oldDocuments.get(i).getDocId()) {
					// 如果修改时间不相等，则文档已修改了
					if (!document.getOperTime().equals(
							oldDocuments.get(i).getOperTime())) {
						// 修改的文章添加到修改的文章集合中
						document.setId(oldDocuments.get(i).getId());
						updateList.add(document);
					}
					// 从旧的文档中移除已经匹配过的文档
					oldDocuments.remove(i);

					isHave = true;
					break;
				}
			}
			if (!isHave) {
				// 新增文档列表
				addList.add(document);
			}
		}
		saveOrModifyDocuments(addList, updateList);
	}

	/**
	 * 
	 * Ansar786 Nov 22, 2015
	 * 
	 * @param addList
	 * @param updateList
	 * @param documents
	 */
	private void saveOrModifyDocuments(List<CnrDocument> addList,
			List<CnrDocument> updateList) {
		int i = 0;
		for (CnrDocument cnrDocument : addList) {
			i += saveDocument(cnrDocument);
			saveDocByScript(cnrDocument, 1); // 1: 表示新增
		}

		int j = 0;
		for (CnrDocument cnrDocument : updateList) {
			j += updateDocument(cnrDocument);
			saveDocByScript(cnrDocument, 2); // 2: 表示修改
		}

		logger.info("新增文档数：" + i + "\n修改文档数：" + j);
	}

	/**
	 * 添加文档 Ansar786 Nov 22, 2015
	 * 
	 * @param document
	 */
	public int saveDocument(CnrDocument document) {
		try {
			memory.create(CnrDocument.class, document);
			return 1;
		} catch (Exception e) {
			logger.error("添加文档时出错：" + e.toString() + "\n=================");
			logger.error(document.getDocId() + "|" + document.getDocTitle()
					+ "\n=================");
		}
		return 0;
	}

	/**
	 * 修改文档 Ansar786 Nov 22, 2015
	 * 
	 * @param cnrDocument
	 */
	public int updateDocument(CnrDocument document) {
		try {
			memory.update(CnrDocument.class, document);
			return 1;
		} catch (Exception e) {
			logger.error("修改文档时出错：" + e.toString() + "\n=================");
			logger.error(document.getDocId() + "|" + document.getDocTitle()
					+ "\n=================");
		}
		return 0;
	}

	/**
	 * 保存文档集合 Ansar786 Nov 23, 2015
	 * 
	 * @param documents
	 */
	public void saveDocuments(List<CnrDocument> documents) {
		int i = 0;
		for (CnrDocument cnrDocument : documents) {
			i += saveDocument(cnrDocument);
			saveDocByScript(cnrDocument, 1); // 1: 表示新增
		}
		logger.info("新增文档数：" + i);
	}

	/**
	 * 修改文档状态 Ansar786 Nov 23, 2015
	 * 
	 * @param channelId
	 * @param documents
	 */
	private void setStatus(int channelId, List<CnrDocument> documents) {
		StringBuffer sql = new StringBuffer();
		try {
			sql.append("update cnr_document set status = 2 where doc_channel = ? and doc_id not in(");
			sql.append(generateQuestionMarks(documents.size()));
			sql.append(")");
			List<Object> params = new ArrayList<Object>();
			params.add(channelId);
			for (CnrDocument document : documents) {
				params.add(document.getDocId());
			}
			if (documents.get(0).getLangId() == 1) {
				sql.append(" and lang_id in(1,2,3)");
			} else if (documents.get(0).getLangId() == 4) {
				sql.append(" and lang_id in(4,5)");
			}
			memory.update(sql, params);
		} catch (Exception e) {
			logger.error("修改文档状态时出错：" + e.toString() + "\n=================");
			logger.error(sql + "\n=================");
		}
	}

	/* 生成占位符 */
	private String generateQuestionMarks(int n) {
		if (n < 1)
			return "";
		StringBuffer buf = new StringBuffer();
		for (int i = 0; i < n; i++) {
			buf.append("?,");
		}
		buf.deleteCharAt(buf.length() - 1);
		return buf.toString();
	}

	/**
	 * Ansar786 Nov 30, 2015
	 * 
	 * @param document
	 * @param lang
	 *            语言分类 1:维文，2：维文ULY，3：维文Selawen，4：哈文，5：哈文Selawen
	 * @param operation
	 *            操作类型：1 表示添加，2 表示修改
	 */
	private void saveDocByScript(CnrDocument document, int operation) {
		switch (document.getLangId()) {
		case 1: // 1：是维文，
			saveOrUpdate(convertToULY(document), operation);
			saveOrUpdate(convertToSelawen(document), operation);
			break;
		case 4: // 4：是哈文
//			saveOrUpdate(convertKzToSelawen(document), operation);
			break;
		default:
			break;
		}
	}

	/**
	 * 根据operation，对文档操作 Ansar786 Dec 1, 2015
	 * 
	 * @param document
	 * @param operation
	 *            1：表示新增，2：表示修改
	 */
	private void saveOrUpdate(CnrDocument document, int operation) {
		if (document != null) {
			if (operation == 1) {
				document.setId(null);
				saveDocument(document);
			} else if (operation == 2) {
				Long id = getDocumentId(document.getDocId(),
						document.getLangId());
				if (id != null) {
					document.setId(id);
					updateDocument(document);
				}
			}
		}
	}

	/**
	 * 维文文档转换维文ULY形式 Ansar786 Dec 1, 2015
	 * 
	 * @param document
	 * @return
	 */
	private CnrDocument convertToULY(CnrDocument document) {
		CnrDocument document2 = document.clone();
		if (document2 == null) {
			return null;
		}
		/**
		 * 2 表示维文ULY
		 */
		document2.setLangId(2);

		document2.setCruser(UyUtil.toULY(document2.getCruser()));
		document2.setDocAuthor(UyUtil.toULY(document2.getDocAuthor()));
		document2.setDocContent(UyUtil.toULY(document2.getDocContent()));
		document2.setDocEditor(UyUtil.toULY(document2.getDocEditor()));
		document2.setDocHtmlCon(UyUtil.toULY(document2.getDocHtmlCon()));
		document2
				.setDocHtmlContent(UyUtil.toULY(document2.getDocHtmlContent()));
		document2.setDocKeyWords(UyUtil.toULY(document2.getDocKeyWords()));
		document2.setDocPubHtmlCon(UyUtil.toULY(document2.getDocPubHtmlCon()));
		document2.setDocSource(UyUtil.toULY(document2.getDocSource()));
		document2.setDocTitle(UyUtil.toULY(document2.getDocTitle()));
		document2.setOperUser(UyUtil.toULY(document2.getOperUser()));

		return document2;
	}

	/**
	 * 维文文档转换维文Selawen形式 Ansar786 Dec 1, 2015
	 * 
	 * @param document
	 * @return
	 */
	private CnrDocument convertToSelawen(CnrDocument document) {
		CnrDocument document2 = document.clone();
		if (document2 == null) {
			return null;
		}
		/**
		 * 3：维文Selawen
		 */
		document2.setLangId(3);

		document2.setCruser(UyUtil.toSelawen(document2.getCruser()));
		document2.setDocAuthor(UyUtil.toSelawen(document2.getDocAuthor()));
		document2.setDocContent(UyUtil.toSelawen(document2.getDocContent()));
		document2.setDocEditor(UyUtil.toSelawen(document2.getDocEditor()));
		document2.setDocHtmlCon(UyUtil.toSelawen(document2.getDocHtmlCon()));
		document2.setDocHtmlContent(UyUtil.toSelawen(document2
				.getDocHtmlContent()));
		document2.setDocKeyWords(UyUtil.toSelawen(document2.getDocKeyWords()));
		document2.setDocPubHtmlCon(UyUtil.toSelawen(document2
				.getDocPubHtmlCon()));
		document2.setDocSource(UyUtil.toSelawen(document2.getDocSource()));
		document2.setDocTitle(UyUtil.toSelawen(document2.getDocTitle()));
		document2.setOperUser(UyUtil.toSelawen(document2.getOperUser()));

		return document2;
	}

	/**
	 * 哈文文档转换哈文Selawen形式 Ansar786 Dec 1, 2015
	 * 
	 * @param document
	 * @return
	 */
	private CnrDocument convertKzToSelawen(CnrDocument document) {
		CnrDocument document2 = document.clone();
		if (document2 == null) {
			return null;
		}
		/**
		 * 5：哈文Selawen
		 */
		document2.setLangId(5);

		document2.setCruser(KzWordConvertUtil.toSelawen(document2.getCruser()));
		document2.setDocAuthor(KzWordConvertUtil.toSelawen(document2
				.getDocAuthor()));
		document2.setDocContent(KzWordConvertUtil.toSelawen(document2
				.getDocContent()));
		document2.setDocEditor(KzWordConvertUtil.toSelawen(document2
				.getDocEditor()));
		document2.setDocHtmlCon(KzWordConvertUtil.toSelawen(document2
				.getDocHtmlCon()));
		document2.setDocHtmlContent(KzWordConvertUtil.toSelawen(document2
				.getDocHtmlContent()));
		document2.setDocKeyWords(KzWordConvertUtil.toSelawen(document2
				.getDocKeyWords()));
		document2.setDocPubHtmlCon(KzWordConvertUtil.toSelawen(document2
				.getDocPubHtmlCon()));
		document2.setDocSource(KzWordConvertUtil.toSelawen(document2
				.getDocSource()));
		document2.setDocTitle(KzWordConvertUtil.toSelawen(document2
				.getDocTitle()));
		document2.setOperUser(KzWordConvertUtil.toSelawen(document2
				.getOperUser()));

		return document2;
	}

	/**
	 * 获取文档编号 Ansar786 Dec 1, 2015
	 * 
	 * @param lang
	 * @param docId
	 * @return
	 */
	public Long getDocumentId(int lang, int docId) {
		try {
			StringBuffer sql = new StringBuffer();
			sql.append("select id from cnr_document where doc_id = ? and lang_id = ?");

			List<Object> params = new ArrayList<Object>();
			params.add(docId);
			params.add(lang);

			Integer id = memory.query(sql, new ColumnHandler<Integer>(
					Integer.class), params);
			if (id == null) {
				return null;
			}
			return id.longValue();
		} catch (Exception e) {
			logger.error("获取文档时出错：" + e.toString());
			return null;
		}
	}

	public static void main(String[] args) {
		CnrDocumentDao dao = new CnrDocumentDao();
		System.out.println(dao.getDocumentId(4, 1121));
	}
}
